package com.banggood.upms.converter;

import com.banggood.upms.bean.po.Permission;
import com.banggood.upms.bean.vo.PermissionVo;
import com.banggood.upms.bean.vo.SystemModuleVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author XuChuangFeng
 * @date 2017/7/4
 */
@Component
public class PermissionConverter {

    public Permission singleInputConverter(PermissionVo vo) {
        return voToPo(vo);
    }

    public List<Permission> inputConverter(List<PermissionVo> voList) {
        List<Permission> poList = new ArrayList<>();
        for(PermissionVo vo : voList) {
            poList.add(voToPo(vo));
        }
        return poList;
    }

    public Map<String, List<SystemModuleVo>> outputConverter(List<Permission> poList) {
        if(CollectionUtils.isEmpty(poList)) {
            return null;
        }
        // 根据系统ID分组
        Map<String, List<Permission>> systemPermsMap = this.groupBySystem(poList);
        Map<String, List<SystemModuleVo>> systemModuleMap = new HashMap<>();
        for(Map.Entry<String, List<Permission>> systemPerms : systemPermsMap.entrySet()) {
            //#1，抽取出模块,K-moduleCode，V-module
            //#2，根据不同模块，分离并抽取出权限点
            Map<String, SystemModuleVo> moduleMap = this.extractModules(systemPerms.getValue());
            List<SystemModuleVo> moduleList = this.convertModuleMapToList(moduleMap);
            systemModuleMap.put(systemPerms.getKey(), moduleList);
        }
        return systemModuleMap;
    }

    /**
     * 将权限元素根据系统ID分组
     * @param poList
     * @return
     */
    private Map<String, List<Permission>> groupBySystem(List<Permission> poList) {
        Map<String, List<Permission>> systemPermsMap = new HashMap<>();
        for(Permission permission : poList) {
            if(!systemPermsMap.containsKey(permission.getSystemId())) {
                List<Permission> permissions = new ArrayList<>();
                permissions.add(permission);
                systemPermsMap.put(permission.getSystemId(), permissions);
            } else {
                systemPermsMap.get(permission.getSystemId()).add(permission);
            }
        }
        return systemPermsMap;
    }

    private List<SystemModuleVo> convertModuleMapToList(Map<String, SystemModuleVo> moduleMap) {
        List<SystemModuleVo> moduleList = new ArrayList<>();
        for(Map.Entry<String, SystemModuleVo> entry : moduleMap.entrySet()) {
            moduleList.add(entry.getValue());
        }
        return moduleList;
    }

    private Map<String, SystemModuleVo> extractModules(List<Permission> poList) {
        Map<String, SystemModuleVo> moduleMap = new HashMap<>();
        for(Permission permission : poList) {
            //是否存在这个模块
            if(!moduleMap.containsKey(permission.getModuleCode())) {
                //module封装
                SystemModuleVo module = this.populateModule(permission);
                module.addPermission(this.poToVo(permission));
                moduleMap.put(permission.getModuleCode(), module);
            } else {
                for(Map.Entry<String, SystemModuleVo> entry : moduleMap.entrySet()) {
                    if(entry.getKey().equalsIgnoreCase(permission.getModuleCode())) {
                        entry.getValue().addPermission(this.poToVo(permission));
                    }
                }
            }
        }
        return moduleMap;
    }

    private SystemModuleVo populateModule(Permission permission) {
        SystemModuleVo module = new SystemModuleVo();
        module.setName(permission.getModuleName());
        module.setCode(permission.getModuleCode());
        return module;
    }

    public PermissionVo singleOutputConverter(Permission po) {
        return poToVo(po);
    }

    private PermissionVo poToVo(Permission po) {
        PermissionVo vo = new PermissionVo();
        BeanUtils.copyProperties(po, vo);
        return vo;
    }

    private Permission voToPo(PermissionVo vo) {
        Permission po = new Permission();
        BeanUtils.copyProperties(vo, po);
        return po;
    }
}
